﻿namespace DeltaGroup.WheelOfJeopardy.ChallengeManager
{
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text.RegularExpressions;

    public class Phrase : IEnumerable<string>, IEqualityComparer<Phrase>
    {
        #region Fields

        private readonly string origPhrase;

        private List<string> keyWords;

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Phrase"/> class.
        /// </summary>
        /// <param name="phraseString">The phrase string.</param>
        public Phrase(string phraseString, List<string> stopWords)
            : this()
        {
            origPhrase = phraseString;

            string temp = phraseString;
            RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline;

            // remove punctuation
            temp = Regex.Replace(temp.Trim(), @"\W", @" ");     

            foreach (string stop in stopWords)
            {
                temp = Regex.Replace(temp, string.Format(StopWords.STOPWORD_SEARCH_PATTERN, stop), " ", options);
            }

            // remove multiple spaces
            temp = Regex.Replace(temp.Trim(), @"[\s]+", @" ");  

            keyWords = temp.Split(new char[] { ' ' }).ToList<string>();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Phrase"/> class.
        /// Prevents parameterless construction.
        /// </summary>
        private Phrase()
        {
        }

        #endregion Constructors

        #region Properties

        /// <summary>
        /// Gets the count.
        /// </summary>
        /// <value>The count.</value>
        public int TokenCount
        {
            get { return keyWords.Count; }
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Determines whether [contains] [the specified token].
        /// </summary>
        /// <param name="token">The token.</param>
        /// <returns>
        /// 	<c>true</c> if [contains] [the specified token]; otherwise, <c>false</c>.
        /// </returns>
        public bool Contains(string token)
        {
            return keyWords.Contains(token);
        }

        /// <summary>
        /// Determines whether [contains] [the specified token].
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="comparer">The comparer.</param>
        /// <returns>
        /// 	<c>true</c> if [contains] [the specified token]; otherwise, <c>false</c>.
        /// </returns>
        public bool Contains(string token, IEqualityComparer<string> comparer)
        {
            return keyWords.Contains(token, comparer);
        }

        /// <summary>
        /// Returns an enumerator that iterates through a collection.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
        /// </returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return keyWords.GetEnumerator();
        }

        /// <summary>
        /// Gets the enumerator.
        /// </summary>
        /// <returns></returns>
        IEnumerator<string> IEnumerable<string>.GetEnumerator()
        {
            return keyWords.GetEnumerator();
        }

        /// <summary>
        /// Equalses the specified x.
        /// </summary>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <returns></returns>
        bool IEqualityComparer<Phrase>.Equals(Phrase x, Phrase y)
        {
            string xString = string.Join(";", x.keyWords);
            string yString = string.Join(";", y.keyWords);
            return xString.Equals(yString);
        }

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        int IEqualityComparer<Phrase>.GetHashCode(Phrase obj)
        {
            return obj.keyWords.GetHashCode();
        }

        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return origPhrase;
        }

        #endregion Methods
    }
}